#!/usr/bin/python

"""
Linked list implementation
"""


class Node(object):
    
    def __init__(self, value=None):
        
        self.__v__ = value
        self.__nn__ = None
        self.__pn__ = None
        
    def getNextNode(self):
        """
        Get next node
        """
        return self.__nn__

    def setNextNode(self, nn):
        """
        Set next node
        """
        self.__nn__ = nn
    
    def getPreviousNode(self):
        """
        Get previous node
        """
        return self.__pn__
    
    def setPreviousNode(self, pn):
        """
        """
        self.__pn__ = pn
        
        
    def getValue(self):
        """
        Get value
        """
        return self.__v__
    
    def setValue(self, v):
        """
        Set value
        """
        self.__v__ = v
        
   
    def __str__(self):
        return "<Node value=%s>"%self.getValue()
        
class LinkedList(object):
    """
    Linked list class
    
    """
    
    def __init__(self, root=None):
        self.__root__ = root
        self.__depth__ = 1 if root else 0

    def __iter__(self):
        """
        implement iterator protocol for the linked list.
        """
        abcd
        
    def getRoot(self):
        return self.__root__
    
    def setRoot(self, node):
        self.__root__ = node
        
    def getDepth(self):
        return self.__depth__
    
    def incrementDepth(self):
        self.__depth__ += 1
    
    def decreaseDepth(self):
        self.__depth__ -= 1
        
    def append(self, new_node):
        """
        Append a node to the end of the list.
        """
        if self.getDepth() == 0:
            self.setRoot(new_node)
            self.incrementDepth()
            return 0
        node = self.getRoot()
        while node.getNextNode() != None: 
            node = node.getNextNode()
        node.setNextNode(new_node)
        new_node.setPreviousNode(node)
        self.incrementDepth()
        
    def delete(self, value):
        """
        Delete a node containing a particular value
        for root index = 0
        """
        node = self.getRoot()
        count = 0
        while node.getValue() != value and count <= self.getDepth():
            node = node.getNextNode()
            count += 1
        bnode = node.getPreviousNode()
        nnode = node.getNextNode()
        bnode.setNextNode(nnode)
        nnode.setPreviousNode(bnode)
        self.decreaseDepth()
        print "Deleted", node
        del node
        
    def print_list(self):
        node = self.getRoot()
        while node.getNextNode() != None:
            print node,
            node = node.getNextNode()
        print node
        
if __name__ == '__main__':
    l = LinkedList()
    n = Node(10)
    l.append(n)
    n = Node(15)
    l.append(n)
    n = Node(23)
    l.append(n)
    n = Node(21)
    l.append(n)
    n = Node(9)
    l.append(n)
    n = Node(23)
    l.append(n)

    print "Length of the linked list, ", l.getDepth()
    print "Linked list"
    l.print_list()
    print
    l.delete(9)
    l.print_list()
    print "Length of the linked list, ", l.getDepth()
